package com.tang.module.system.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tang.common.resources.Kv;
import com.tang.module.system.entity.LogApi;
import com.tang.module.system.entity.NameAndValue;
import com.tang.module.system.mapper.LogApiMapper;
import com.tang.module.system.mapper.LogInterfaceMapper;
import com.tang.module.system.service.StatisticsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author tang
 * @date 2022/3/14 16:36
 */
@Service("statisticsService")
public class StatisticsServiceImpl implements StatisticsService {

    @Autowired
    private LogApiMapper logApiMapper;

    @Autowired
    private LogInterfaceMapper logInterfaceMapper;

    @Override
    public Map<String,Map<String, Object>> byDay() {
        //本月总api
        List<Kv<String, Integer>> kvs = logApiMapper.byDay(DateUtil.beginOfMonth(new Date()).toJdkDate());
        //计费api
        List<Kv<String, Integer>> kvList = logInterfaceMapper.byDay(DateUtil.beginOfMonth(new Date()).toJdkDate());
        Map<String,Map<String, Object>> map = new HashMap<>(2);
        HashMap<String, Object> map1 = new HashMap<>(3);
        //获得总api数据
        map.put("v1",map1);
        map1.put("title","本月访问");
        map1.put("v",kvs.parallelStream().map(Kv::getKey).collect(Collectors.toList()));
        map1.put("k",kvs.parallelStream().map(Kv::getValue).collect(Collectors.toList()));
        HashMap<String, Object> map2 = new HashMap<>(3);
        //计费api数据
        map.put("v2",map2);
        map2.put("title","本月计费API访问");
        map2.put("v",kvList.parallelStream().map(Kv::getKey).collect(Collectors.toList()));
        map2.put("k",kvList.parallelStream().map(Kv::getValue).collect(Collectors.toList()));
        return map;
    }

    @Override
    public Map<String, String> recordStatistics() {
        //总访问数
        Integer total = logApiMapper.selectCount(null);
        //本周总访问数
        Integer monthTotal = logApiMapper.selectCount(Wrappers.<LogApi>lambdaQuery().ge(LogApi::getCreateTime, DateUtil.beginOfWeek(new Date()).toJdkDate()));
        //总登录数量
        Integer loginTotal = logApiMapper.selectCount(Wrappers.<LogApi>lambdaQuery().eq(LogApi::getTitle, "登录").eq(LogApi::getSuccess, true));
        //本周登录次数
        Integer loginMonthTotal = logApiMapper.selectCount(Wrappers.<LogApi>lambdaQuery().eq(LogApi::getTitle, "登录").eq(LogApi::getSuccess, true).ge(LogApi::getCreateTime, DateUtil.beginOfWeek(new Date()).toJdkDate()));
        //计费Api次数
        Integer apiTotal = logInterfaceMapper.selectCount(null);
              Map<String, String> map = new HashMap<>(5);
        map.put("total", String.valueOf(total));
        map.put("monthTotal", String.valueOf(monthTotal));
        map.put("loginTotal", String.valueOf(loginTotal));
        map.put("loginMonthTotal", String.valueOf(loginMonthTotal));
        map.put("apiTotal", String.valueOf(apiTotal));
        return map;
    }

    @Override
    public LinkedList<NameAndValue> accessSource() {
        List<LogApi> logApis = logApiMapper.selectList(Wrappers.<LogApi>lambdaQuery().select(LogApi::getAddress));
        //取出城市和访问次数
        Map<String, Long> cityMap = logApis.stream().filter(logApi -> !"本地".equals(logApi.getAddress()) && StringUtils.isNotBlank(logApi.getAddress())).peek(logApi -> {
            //获得访问地址，国家-省-市-区/县
            //这里只获取市
            String[] split = logApi.getAddress().split("-");
            //去除空白字符和null
            List<String> collect = Arrays.stream(split).filter(s -> StringUtils.isNotEmpty(s) && ! "null".equals(s)).collect(Collectors.toList());
            if (collect.size() >= 3){
                logApi.setAddress(collect.get(2));
            }else {
                logApi.setAddress(collect.get(collect.size() - 1));
            }
        }).collect(Collectors.groupingBy(LogApi::getAddress, Collectors.counting()));
        //访问量前10的城市
        Set<String> stringSet = cityMap.keySet().stream().sorted(Comparator.comparing(cityMap::get).reversed()).limit(10).collect(Collectors.toSet());
        LinkedList<NameAndValue> list = new LinkedList<>();
        for (String s : stringSet) {
            list.add( new NameAndValue(s,cityMap.get(s)));
        }
        return list;
    }

}
